﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppEventLib
{
    [Serializable]
    public class AppClient
    {
        public event EventHandler<Exception> Error;
        RestClient client;
        public string BaseUrl;
        public List<Cookie> Cookies = new List<Cookie>();

        public string UserID { get; set; }

        public AppClient(string baseUrl)
        {
            this.BaseUrl = baseUrl;
            client = new RestClient(baseUrl);
        }

        #region helper methods from request
        private RestRequest LoadRequest(string apiUrl)
        {
            var request = new RestSharp.RestRequest(apiUrl, RestSharp.Method.POST);
            foreach (var cookie in Cookies)
            {
                request.AddCookie(cookie.Name, cookie.Value);
            }
            return request;
        }

        private JsonResp GetResponse(RestRequest request)
        {
            var resp = client.Execute<JsonResp>(request);
            if (resp.ErrorException != null)
            {
                Error?.Invoke(this, resp.ErrorException);
                return null;
            }
            else if ((int)resp.StatusCode >= 400)
            {
                Error?.Invoke(this, new Exception(resp.StatusDescription, resp.Content != null ? new Exception(resp.Content) : null));
                return null;
            }
            Parameter cookie = null;
            if ((cookie = resp.Headers.FirstOrDefault(x => x.Name == "Set-Cookie")) != null)
            {
                lock (Cookies)
                {
                    var pair = cookie.Value.ToString().Split(new char[] { '=' }, 2);
                    var c = new Cookie { Name = pair[0], Value = GetCookieValue(pair[1]) };
                    var index = Cookies.FindIndex(x => x.Equals(c));
                    if (index != -1)
                    {
                        Cookies[index] = c;
                    }
                    else
                        Cookies.Add(c);
                }
            }
            return resp.Data;
        }

        public void IncreaseCorRun(string appId, string appVersion)
        {
            var request = LoadRequest("api/app/IncreaseCorRun");
            request.AddParameter("id", appId);
            request.AddParameter("version", appVersion);
            var resp = GetResponse(request);
        }

        public void IncreaseAppRun(string appId, string appVersion)
        {
            var request = LoadRequest("api/app/IncreaseAppRun");
            request.AddParameter("id", appId);
            request.AddParameter("version", appVersion);
            var resp = GetResponse(request);
        }


        private string GetCookieValue(string value)
        {
            var array = value.Split(new string[] { "; " }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var item in array)
            {
                if (item.IndexOf("httponly") == 0
                    || item.IndexOf("path") == 0
                    || item.IndexOf("domain") == 0
                    )
                    continue;
                return item;
            }
            return string.Empty;
        }

        private T GetResponse<T>(RestRequest request)
        {
            return GetResponse(request).As<T>();
        }
        #endregion


    }
    [Serializable]
    public class Cookie
    {
        public string Name { get; set; }
        public string Value { get; set; }
        public override bool Equals(object obj)
        {
            return this.Name == (obj as Cookie).Name;
        }
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
    }
}
